import { AREA_MOVE_DURATION, BLOCK_ELIMINATE_LIMIT, BLOCK_TAG_ADDITION, CUSTOM_EVENT_NAME, NODE_POOL_NAME } from "../Common/Constant";
import { GameData } from "../Common/GameData";
import LanguagetileTile from "../Common/Language";
import SingleBlockController from "../Game/SingleBlockController";
import getEventEmiter from "../Libraries/EventEmitter";
import NodePool from "../Libraries/NodePool";
import PlatformSystem from "../Platform/PlatformSystem";
import GameSceneController from "../Scenes/GameSceneController";
import ArchiveSystem from "../System/ArchiveSystem";
import * as DataCollectSystem from "../System/DataCollectSystem";
import GamingSystem from "../System/GamingSystem";
import SceneManagerSystem from "../System/SceneManagerSystem";
import SkinSystem from "../System/SkinSystem";
import CatcherController from "./CatcherController";
import SingleCatcherController from "./SingleCatcherController";
import Archive from "../Common/Archive";
import CCLog from "../CCLog";
import GameTileStaticData from "../GameStaticData";
import propFly from "./propFly";
const { ccclass, property } = cc._decorator;
const [layerPosX, layerPosY] = [0, 0];

@ccclass
export default class GamePlayController extends cc.Component {
    public static I: GamePlayController;

    @property(cc.Prefab)
    public prefabBlock: cc.Prefab = null;

    @property(cc.Node)
    public nodeLayerMap: cc.Node = null;

    @property(cc.Node)
    public nodeTopArea: cc.Node = null;

    @property(cc.SpriteFrame)
    jinbiSp:cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    moneySp:cc.SpriteFrame = null;


    @property(cc.Node)
    public topMax: cc.Node = null;

    @property(cc.Node)
    public centerNode: cc.Node = null;

    @property(cc.Node)
    public bottomMin: cc.Node = null;

    private _revivedTime: number = 1;
    private _mapLayers: cc.Node[] = [];
    private _existBlocks: SingleBlockController[] = []; //所有的块
    private _blockFlags: boolean[][] = [];
    private _blocksNum: number = 0;
    private _layerPosY: number = 0;
    private _maxMapHeight: number = 0;

    private _refreshing: boolean = false;
    private _backing: boolean = false;
    private clicktime = 0


    public async onLoad() {
        GamePlayController.I = this;
        let winSize = cc.winSize
        //CCLog.log("++++++宽高比",winSize.height/winSize.width)
        if(winSize.height/winSize.width <= 1.9){
            this.nodeLayerMap.setScale(0.85)
        }else{
             
            
        }
        this.moneySp = await LanguagetileTile.BlockMoneyIcon()
        // getEventEmiter().on(CUSTOM_EVENT_NAME.onSceneChanged, this.__mapsGoUp, this);
        //getEventEmiter().on(CUSTOM_EVENT_NAME.onSceneChangedComplete, this.showMaps, this);
        
    }

    public onDestroy() {
        // getEventEmiter().off(CUSTOM_EVENT_NAME.onSceneChanged, this.__mapsGoUp, this);
        //getEventEmiter().off(CUSTOM_EVENT_NAME.onSceneChangedComplete, this.showMaps, this);
    }
  
    /**
     * 清除场景内地图
     */
    public cleanMap(): void {
        this._blockFlags = [];
        this._mapLayers.forEach((v: cc.Node) => {
            v.children.forEach((block: cc.Node) => {
                NodePool.putItem(NODE_POOL_NAME.singleBlock, block);
            });
            v.destroy();
        });
        this._mapLayers.length = 0;
        this._mapLayers = [];
        this._blocksNum = 0;
    }

    public setMap(coinNum:number,redBagNum:number): void {
        const { blockTypeNum, map } = GamingSystem.mapInfo;
        let guidcoin = false;
        let issub = 0;
        //if (GameData.LevelData.passNum == 2 && GameData.LevelData.novice2 == 0){
        if (GameData.LevelData.passNum == 2 && GameData.AccountData.cointotal<=0){
            if (GameTileStaticData.isShenHeModel) {
                //审核版本不显示金币
                guidcoin = false;
            }else{
                guidcoin = false;
            }
            
        }
        if (guidcoin){
            issub = 1;
            
            if (coinNum <= 0){
                coinNum = 1;
            }
        }

        const skinSelections: cc.SpriteFrame[] = SkinSystem.getSkinUsing().sort(
            () => Math.random() < 0.5 ? 1 : -1
        ).slice(0, blockTypeNum);
            
        CCLog.log("+++coinNum===",coinNum);
        CCLog.log("redBagNum===",redBagNum);
        let skinSorted: cc.SpriteFrame[] = [];
        for (let i: number = 0; i < GamingSystem.mapBlocksNum / BLOCK_ELIMINATE_LIMIT; i++) {
            if (i < coinNum){
                if (issub == 0){
                    issub = 0
                    for (let b: number = 0; b < BLOCK_ELIMINATE_LIMIT; b++) {
                        skinSorted.push(this.jinbiSp);
                    }
                }
            }else if (i < coinNum+redBagNum){
                for (let b: number = 0; b < BLOCK_ELIMINATE_LIMIT; b++) {
                    skinSorted.push(this.moneySp);
                }
            }else{
                let index = i % skinSelections.length;
                for (let b: number = 0; b < BLOCK_ELIMINATE_LIMIT; b++) {
                    skinSorted.push(skinSelections[index]);
                }
            }
        }
        skinSorted.sort(() => Math.random() < 0.5 ? 1 : -1);
        if (guidcoin){
            skinSorted.push(this.jinbiSp)
            skinSorted.push(this.jinbiSp)
            skinSorted.push(this.jinbiSp)
        }
        CCLog.log("skinSorted.length===",skinSorted.length);
        for (let i: number = 0; i < map.length; i++) {
            let layer = new cc.Node();
            
            layer.active = false;
            this._mapLayers.push(layer);
            
            layer.zIndex = i + 1;
            const { width, height, x, y } = map[i];
            this._blockFlags.push([]);
            for (let j: number = 0; j < x.length; j++) {
                let block = GamingSystem.mapInfo.level === 1 ? cc.instantiate(this.prefabBlock) : NodePool.getItem(NODE_POOL_NAME.singleBlock, this.prefabBlock);
               
                let blockController = block.getComponent(SingleBlockController);
                blockController.initScale();
                layer.addChild(block);
                
                let blockwidth = block.width * block.scale;
                let blockHeight = block.height * block.scale;

                CCLog.log("blockwidth=====",blockwidth);
                CCLog.log("blockHeight=====",blockHeight);
                this._existBlocks.push(blockController);
                this._blockFlags[i].push(true);
               
                layer.setContentSize(blockwidth * width, blockHeight * height);
                block.setPosition(
                    blockwidth * x[j] - layer.width / 2 + blockwidth / 2,
                    blockHeight * (height - 1 - y[j]) - layer.height / 2 + blockHeight / 2
                );
                CCLog.log("block/getpos==",block.getPosition());
                CCLog.log("block/getpos==this.nodeLayerMap",this.nodeLayerMap.getPosition());
                blockController.init(skinSorted[this._blocksNum], j + 1, i + 1 + BLOCK_TAG_ADDITION, i, j);
                this._blocksNum += 1;
            }
            layer.setPosition(0,0);
            this.nodeLayerMap.addChild(layer);
            
            if (layer.height > this._maxMapHeight) this._maxMapHeight = layer.height;
        }
    }

    public showMaps(eventType: string) {
        if (eventType === 'setMap') {
            console.log("+++++收到setMap")
            let catcher = CatcherController.I.node.parent;
            let topAreaPos = catcher.parent.convertToNodeSpaceAR(this.nodeTopArea.convertToWorldSpaceAR(cc.v2(0, 0)));
            let centerPosY = (catcher.y + catcher.height * (1 - catcher.anchorY) + topAreaPos.y - this.nodeTopArea.height / 2) / 2;
            let closerPosY = catcher.y + catcher.height + this._maxMapHeight / 2 + 140;
            this._layerPosY = centerPosY < closerPosY ? centerPosY : closerPosY;
            // this._layerPosY -= Helper.isNormalScreen() ? 30 : 20;

            this._mapLayers.forEach((n: cc.Node, ni: number, a: cc.Node[]) => {
                this.mapLayerAction(n, ni, () => {
                    if (ni === a.length - 1) {
                        getEventEmiter().emit(CUSTOM_EVENT_NAME.onGameStart);
                    }
                });
            });
        }
    }

    public mapLayerAction(layer: cc.Node, i: number, callback?: Function): void {
        cc.Tween.stopAllByTarget(layer)
        switch (i % 4) {
            case 0:
                layer.setPosition(-900, this._layerPosY);
                break;
            case 1:
                layer.setPosition(layerPosX, 1400);
                break;

            case 2:
                layer.setPosition(900, this._layerPosY);
                break;

            case 3:
                layer.setPosition(layerPosX, -1400);
                break;
        }
        layer.active = true;
       
        let pos1 = this.topMax.parent.convertToWorldSpaceAR(this.topMax.position); 
        let pos2 = this.bottomMin.parent.convertToWorldSpaceAR(this.bottomMin.position);
        let pos3 = this.centerNode.parent.convertToWorldSpaceAR(this.centerNode.position);
        
    
        let temp1 =  Math.abs(pos3.y -pos2.y);
        let temp2 =  Math.abs(pos3.y -pos1.y);
        const width = temp2 -temp1;
      
        cc.tween(layer)
            .delay(0.07 * i)
            //.to(0.2, { x: layerPosX, y: this._layerPosY })
            .to(0.2, { x: 0, y:width/2})
            .delay(0.2)
            .call(() => { callback && callback(); })
            .start();
    }

    /**
     * 点击撤回功能
     */
    public async recall(cost: boolean = true): Promise<void> {
        if (GamingSystem.gameOver || GamingSystem.gameComplete || this._refreshing) return;
        if (cost){
            if (this.clicktime > Date.now()){
                return;
            }
            this.clicktime = Date.now() + 1000
        }
        if (cost && ArchiveSystem.localData.recallNum <= 0) {
            await SceneManagerSystem.showPropUsePanel(1,()=>{
                ArchiveSystem.localData.recallNum += 2;
                // PlatformSystem.platform.showToast({
                //     title: '成功获得奖励',
                //     duration: 2000,
                // });
            })
            // PlatformSystem.platform.showRewardVideo(() => {
            //     ArchiveSystem.localData.recallNum += 1;
            //     PlatformSystem.platform.showToast({
            //         title: '成功获得奖励',
            //         duration: 2000,
            //     });
            //     DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.recallVideoSuccess);
            // });
            // DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.recallVideo);
            return;
        }
        let b = CatcherController.I.getLastBlock();
        if (b) {
            b.recover();
            this._existBlocks.push(b);
            this._blockFlags[b.layerNumber][b.indexNumber] = true;
            if (cost) ArchiveSystem.localData.recallNum -= 1;
            DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.recall);
        } else {
            PlatformSystem.platform.showToast({
                title: '无需撤回',
            });
        }
    }
    public  setIsReCall(value:boolean):void
    {
        this._backing = value;
    }
    /**
     * 点击刷新功能
     */
    public async refresh(): Promise<void> {
        if (GamingSystem.gameOver || GamingSystem.gameComplete || this._refreshing || this._backing) return;
        if (this.clicktime > Date.now()){
            return;
        }
        this.clicktime = Date.now() + 1000
        if (ArchiveSystem.localData.refreshNum <= 0) {
            await SceneManagerSystem.showPropUsePanel(0,()=>{
                ArchiveSystem.localData.refreshNum += 3;
                // PlatformSystem.platform.showToast({
                //     title: '成功获得奖励',
                //     duration: 2000,
                // });
                propFly.I.flyFreshAction()
            })

            // PlatformSystem.platform.showRewardVideo(() => {
            //     ArchiveSystem.localData.refreshNum += 1;
            //     PlatformSystem.platform.showToast({
            //         title: '成功获得奖励',
            //         duration: 2000,
            //     });
            //     DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.refreshVideoSuccess);
            // });
            // DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.refreshVideo);
            return;
        }
        this._refreshing = true;
        this._existBlocks.sort((a, b) => { return Math.random() > 0.5 ? 1 : -1 });
      
        let blockCounter: number = 0;
        const map = GamingSystem.mapInfo.map;
        for (let i: number = 0; i < this._blockFlags.length; i++) {
            if(!map[i])
            {
                continue;
            }
            const layer = this._mapLayers[i];
         
            const { height, x, y } = map[i];
            
            const flags = this._blockFlags[i];
            for (let j: number = 0; j < flags.length; j++) {
                if (!flags[j]) continue;
                let blockController = this._existBlocks[blockCounter];
                let block = blockController.node;

                let blockwidth = block.width * block.scale;
                let blockHeight = block.height * block.scale;

                block.setParent(layer);
                block.setPosition(
                    blockwidth * x[j] - layer.width / 2 + blockwidth / 2,
                    blockHeight * (height - 1 - y[j]) - layer.height / 2 + blockHeight / 2
                );
                blockController.init(blockController.blockSkin.spriteFrame, j + 1, i + 1 + BLOCK_TAG_ADDITION, i, j);
                blockCounter += 1;
            }
            this.mapLayerAction(
                layer,
                i,
                () => {
                    if (i === this._blockFlags.length - 1) this._refreshing = false;
                }
            );
        }
        ArchiveSystem.localData.refreshNum -= 1;
        DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.refresh);
    }

    /**
     * 点击提示功能
     */
    public async hint(): Promise<void> {
        if (GamingSystem.gameOver || GamingSystem.gameComplete || this._refreshing) return;
        if (this.clicktime > Date.now()){
            return;
        }
        this.clicktime = Date.now() + 1000
        if (ArchiveSystem.localData.hintNum <= 0) {
            await SceneManagerSystem.showPropUsePanel(2,()=>{
                ArchiveSystem.localData.hintNum += 3;
                // PlatformSystem.platform.showToast({
                //     title: '成功获得奖励',
                //     duration: 2000,
                // });
                propFly.I.flyTipAction()
            })

            // PlatformSystem.platform.showRewardVideo(() => {
            //     ArchiveSystem.localData.hintNum += 1;
            //     PlatformSystem.platform.showToast({
            //         title: '成功获得奖励',
            //         duration: 2000,
            //     });
            //     DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.hintVideoSuccess);
            // });
            // DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.hintVideo);
            return;
        }
        let showed: boolean = false;
        const blankCatcherNum = CatcherController.I.getBlankCatcherNum();
        const blockAvailable = this._existBlocks.filter(v => true).reverse();
        const catchers = CatcherController.I.catchers;
        const setedCatcher: SingleCatcherController[] = catchers.filter(v => !!v.getCurrentBlock());
        for (let i: number = 0; i < setedCatcher.length; i++) {
            let blockSkin = setedCatcher[i].getCurrentBlock().blockSkin.spriteFrame;
            let sameNum = setedCatcher.filter(v => {
                return v.getCurrentBlock().blockSkin.spriteFrame == blockSkin;
            }).length;
            if (sameNum >= BLOCK_ELIMINATE_LIMIT) continue;
            if (sameNum + blankCatcherNum < BLOCK_ELIMINATE_LIMIT) continue;
            let existSame: SingleBlockController[] = blockAvailable.filter(v => v.blockSkin.spriteFrame == blockSkin);
            if (existSame.length + sameNum < BLOCK_ELIMINATE_LIMIT) continue;
            for (let b: number = 0; b < BLOCK_ELIMINATE_LIMIT - sameNum; b++) {
                existSame[b].collect();
            }
            showed = true;
            break;
        }
        if (!showed) {
            if (blankCatcherNum >= BLOCK_ELIMINATE_LIMIT) {
                for (let e: number = 0; e < blockAvailable.length; e++) {
                    let blockSkin = blockAvailable[e].blockSkin.spriteFrame;
                    let existSame: SingleBlockController[] = blockAvailable.filter(v => v.blockSkin.spriteFrame == blockSkin);
                    if (existSame.length < BLOCK_ELIMINATE_LIMIT) continue;
                    for (let b: number = 0; b < BLOCK_ELIMINATE_LIMIT; b++) {
                        existSame[b].collect();
                    }
                    showed = true;
                    break;
                }
            }
        }
        if (showed) {
            ArchiveSystem.localData.hintNum -= 1;
            DataCollectSystem.reportUserBehaviorBranchAnalytics(DataCollectSystem.LOG_KEY_GAME_PAGE.hint);
        } else {
            PlatformSystem.platform.showToast({
                title: '无法消除',
                duration: 2000,
            });
        }
    }

    /**
     * 减少块儿的记数
     * @param checkComplete 是否检测通关
     */
    public subBlockNum(): void {
        this._blocksNum -= 1;
    }

    /**
     * 更新地图上剩余的块
     */
    public updateBlockLeft(block: SingleBlockController): void {
        this._existBlocks.splice(this._existBlocks.indexOf(block), 1);
        this._blockFlags[block.layerNumber][block.indexNumber] = false;
    }


    /**
     * 获取当前剩余块的数量
     */
    public getBlocksLeftNum(): number {
        return this._blocksNum;
    }

    /**获取现存的block */
    public getBlocksAvailable(): SingleBlockController[] {
        return this._existBlocks.filter((v: SingleBlockController) => {
            return v.available;
        });
    }

    /**
     * 判断是否通关
     */
    public checkResult(s: string = ''): void {
        if (CatcherController.I.isNotFull()) {
            if (GamePlayController.I.getBlocksLeftNum() <= 0) {
                this.LevelSuccess();
            }
        } else {
            this.LevelFail();
        }
    }

    public getRevivedTime(): number {
        return this._revivedTime;
    }

    public isJinBiBlock(block:SingleBlockController){
        return this.jinbiSp == block.blockSkin.spriteFrame
    }

    public isMoneyBlock(block:SingleBlockController){
        return this.moneySp == block.blockSkin.spriteFrame
    }

    public LevelSuccess(): void {

        Archive.checkTask(1);
        GamingSystem.gameComplete = true;
        SceneManagerSystem.showSucessLayer();
        getEventEmiter().emit(CUSTOM_EVENT_NAME.onGameComplete);
        DataCollectSystem.reportLevelComplete(GamingSystem.mapInfo.level);
    }

    public async LevelFail(): Promise<void> {
        GamingSystem.gameOver = true;
        await SceneManagerSystem.showFailLayer(async (result)=>{
            GamingSystem.gameOver = false;
            if (result == 0){
                GamingSystem.realStartLevel();
            }else{
                this.recall(false)
                this.recall(false)
                this.recall(false)
            }
        });
        this._revivedTime -= 1;
        DataCollectSystem.reportLevelFail(GamingSystem.mapInfo.level);
    }

    // /**
    //  * 关闭场景时地图向上
    //  */
    // private __mapsGoUp(): void {
    //     console.log("阿斯顿减肥")
    //     this._mapLayers.forEach((v: cc.Node) => {
    //         cc.tween(v)
    //             .to(AREA_MOVE_DURATION, { y: v.y + 1400 })
    //             .start();
    //     });
    // }
}
